package org.skydiveapplibrary.util;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;

import org.skydiveapplibrary.R;
import org.skydiveapplibrary.util.DatabaseExportUtil;
import org.skydiveapplibrary.util.ZipUtil;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;

public class ExportTask extends AsyncTask<ExportDestination, Integer, Integer>
{	
	// results types
	private static final int SUCCESS = 10;
	private static final int SUCCESS_SEND_EMAIL = 20;
	private static final int ERROR = 30;
	
	// export file names
	private static final String XML_EXPORT_FILE_NAME = "skydiving_logbook.xml";
	private static final String CSV_EXPORT_FILE_NAME = "skydiving_logbook.csv";
	private static final String ZIP_EXPORT_FILE_NAME = "skydiving_logbook.zip";
	// dropbox folder
	private static final String DROPBOX_FOLDER = "skydiving_logbook";

	private Activity activity;
	private ProgressDialog progressDialog = null;
	
	public ExportTask(Activity activity)
	{
		this.activity = activity;
	}
	
	@Override
	protected void onPreExecute()
	{
		// show dialog
		progressDialog = ProgressDialog.show(activity,
				"",
				activity.getString(R.string.import_export_export_progress_message),
				true, true);
		progressDialog.show();
	}

	@Override
	protected Integer doInBackground(ExportDestination... destinations)
	{
		int result = SUCCESS;
		ExportDestination destination = destinations[0];
		try
		{
			if (destination == ExportDestination.Email)
			{
				result = exportToEmail();
			}
			else if (destination == ExportDestination.SDCard)
			{
				result = exportToSDCard();
			}
			else if (destination == ExportDestination.DropBox)
			{
				result = exportToDropBox();
			}
		}
		catch (Exception ex)
		{
			Log.e(ExportTask.class.getCanonicalName(), ex.getMessage());
			result = ERROR;
		}

		return result;
	}
	
	@Override
	protected void onPostExecute(Integer result)
	{
		// dismiss dialog
		progressDialog.dismiss();
		
		// get resource for result
		int resourceId = (result == SUCCESS || result == SUCCESS_SEND_EMAIL) ?
			R.string.import_export_export_success :
			R.string.import_export_export_error;
		
		// show toast
		Toast status = Toast.makeText(activity, resourceId, Toast.LENGTH_SHORT);
		status.show();

		// send email if necessary
		if (result == SUCCESS_SEND_EMAIL)
		{
			sendEmail();
		}
	}
	
	private int exportToSDCard()
		throws Exception
	{
		// get xml/csv writers
		Writer xmlWriter = getSDCardFileWriter(XML_EXPORT_FILE_NAME);
		Writer csvWriter = getSDCardFileWriter(CSV_EXPORT_FILE_NAME);
		// create export util
		DatabaseExportUtil util = new DatabaseExportUtil(activity);
		// do export
		util.exportDatabase(xmlWriter, csvWriter);
		
		// close writers
		xmlWriter.close();
		csvWriter.close();
		
		return SUCCESS;
	}
	
	private int exportToDropBox()
		throws Exception
	{
		// get xml/csv writers 
		Writer xmlWriter = getAppFileWriter(XML_EXPORT_FILE_NAME);
		Writer csvWriter = getAppFileWriter(CSV_EXPORT_FILE_NAME);
		// create export util
		DatabaseExportUtil util = new DatabaseExportUtil(activity);
		// do export
		util.exportDatabase(xmlWriter, csvWriter);

		// close writers
		xmlWriter.close();
		csvWriter.close();
		
		// get files
		File xmlFile = new File(activity.getApplication().getFilesDir(), XML_EXPORT_FILE_NAME);
		File csvFile = new File(activity.getApplication().getFilesDir(), CSV_EXPORT_FILE_NAME);
		// upload to dropbox
		DropBoxClient.getInstance().putFiles(DROPBOX_FOLDER, xmlFile, csvFile);

		return SUCCESS;
	}
	
	private int exportToEmail()
		throws Exception
	{
		// get xml/csv writers 
		Writer xmlWriter = getAppFileWriter(XML_EXPORT_FILE_NAME);
		Writer csvWriter = getAppFileWriter(CSV_EXPORT_FILE_NAME);
		// create export util
		DatabaseExportUtil util = new DatabaseExportUtil(activity);
		// do export
		util.exportDatabase(xmlWriter, csvWriter);

		// close writers
		xmlWriter.close();
		csvWriter.close();

		// zip results
		// get file list
		List<File> zipFiles = new ArrayList<File>();
		zipFiles.add(new File(activity.getApplication().getFilesDir(), XML_EXPORT_FILE_NAME));
		zipFiles.add(new File(activity.getApplication().getFilesDir(), CSV_EXPORT_FILE_NAME));
		// get zip output stream
		FileOutputStream zipOutputStream = activity.openFileOutput(ZIP_EXPORT_FILE_NAME, Context.MODE_WORLD_READABLE);
		// create zip
		ZipUtil.createZip(zipOutputStream, zipFiles);
		
		return SUCCESS_SEND_EMAIL;
	}

	private Writer getSDCardFileWriter(String fileName)
		throws IOException
	{
		// get file path
		String filePath = Environment.getExternalStorageDirectory() + "/" + fileName;
		File file = new File(filePath);
		if (!file.exists())
		{
			file.createNewFile();
		}
		
		return new FileWriter(file);	
	}
	
	private Writer getAppFileWriter(String fileName)
		throws FileNotFoundException
	{
		FileOutputStream fos = activity.openFileOutput(fileName, Context.MODE_WORLD_READABLE);
		return new OutputStreamWriter(fos);
	}
	
	private void sendEmail()
	{
		// construct uri
		Uri zipUri = Uri.fromFile(new File(
				activity.getApplication().getFilesDir(), ZIP_EXPORT_FILE_NAME));
		
		// start email activity
		Intent emailIntent = new Intent(Intent.ACTION_SEND); 
		emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Skydiving Logbook");
		emailIntent.putExtra(Intent.EXTRA_TEXT, activity.getString(R.string.import_export_export_message));
		emailIntent.putExtra(Intent.EXTRA_STREAM, zipUri);
		emailIntent.setType("application/zip");
		activity.startActivity(Intent.createChooser(emailIntent, "Send mail..."));
    }
}